#include "./../../../include/online/Tools/Configuration.h"
#include "./../../../include/online/Server/SearchEngineServer.h"
#include "./../../../include/online/Reactor/TcpServer.h"
#include "./../../../include/online/Tools/ProtocolParser.h"
#include "./../../../include/online/CacheSystem/CacheManager.h"
#include "./../../../include/online/WebPageQuery/RedisClient.h"
#include "./../../../include/online/Tools/CppJieba.h"
#include "./../../../include/online/WebPageQuery/WebPage.h"
#include "./../../../include/online/WebPageQuery/WebQuery.h"
#include <stdio.h>
#include <stdlib.h>
#include <nlohmann/json.hpp>

using nlohmann::json;


using namespace std;
using nlohmann::json;

SearchEngineServer::SearchEngineServer(size_t threadNum, size_t quesize, const string &ip, unsigned int port)
: _pool(threadNum, quesize)
, _tcpserver(ip, port)
{

}

SearchEngineServer::~SearchEngineServer()
{

}

// 服务器的启动与停止
void SearchEngineServer::start()
{
    CacheManager::getInstance();
    _pool.start();
    // 注册所有的回调
    _tcpserver.setAllCallback(std::bind(&SearchEngineServer::onNewConnection, this, std::placeholders::_1),
                              std::bind(&SearchEngineServer::onMessage, this, std::placeholders::_1),
                              std::bind(&SearchEngineServer::onClose, this, std::placeholders::_1));
    _tcpserver.start();
}

void SearchEngineServer::stop()
{
    _pool.stop();
    _tcpserver.stop();
}

// 连接建立
void SearchEngineServer::onNewConnection(const TcpConnectionPtr &con)
{
    cout << con->toString() << " has connected!!!" << endl;
}

// 消息到达（文件描述符可读）
void SearchEngineServer::onMessage(const TcpConnectionPtr &con)
{
    // 客户端发送的消息
    string msg = con->receive();
    cout << ">>recv client msg=" << msg << endl;
    msg.pop_back();

    // 将dotask发送给工作线程
    _pool.addTask(std::bind(&SearchEngineServer::doTaskThread, this, con, msg));
}

// 连接断开
void SearchEngineServer::onClose(const TcpConnectionPtr &con)
{
    cout << con->toString() << " has closed!!!" << endl;
}

void SearchEngineServer::doTaskThread(const TcpConnectionPtr &conn, const string &msg)
{
    json recvInfo = ProtocolParser::doParse(msg);
    json sendInfo;
    string sendString;
    if (recvInfo["flag"] == "1")                  // 执行候选词推荐业务
    {
        KeyRecommender keyword(recvInfo["info"]); // 开始关键字查询
        sendInfo = keyword.repstr();              // 返回客户端的信息
        sendString = sendInfo.dump();
        cout << " " << sendString << endl;
    }
    else if(recvInfo["flag"] == "2")              // 执行网页查询业务
    {
        WebQuery wq;
        string queryWords = recvInfo["info"];
        sendString = wq.doQuery(queryWords);
    }

    // 将经过查询后的数据返回给客户端
    conn->sendInLoop(sendString);
}
